/* eslint-disable @typescript-eslint/no-unused-vars */
import { ModelError } from '@ibiz-template/core';
import {
  CodeListItem,
  convertNavData,
  getWFContext,
  IModalData,
  OpenAppViewCommand,
  parseUserParams,
} from '@ibiz-template/runtime';
import { IAppCodeList, IDEGridFieldColumn } from '@ibiz/model-core';
import { clone } from 'ramda';
import { GridColumnController } from '../../grid/grid-column.controller';
import { GridRowState } from '../../grid/grid-row.state';

/**
 * 表格属性列控制器
 * @return {*}
 * @author: zhujiamin
 * @Date: 2022-09-01 18:25:20
 */
export class GridFieldColumnController extends GridColumnController<IDEGridFieldColumn> {
  /**
   * 代码表项
   *
   * @author lxm
   * @date 2022-09-28 16:09:51
   * @type {readonly}
   */
  codeListItems?: readonly CodeListItem[];

  /**
   * 代码表模型
   * @return {*}
   * @author: zhujiamin
   * @Date: 2023-05-24 10:55:50
   */
  codeList: IAppCodeList | undefined = undefined;

  /**
   * 是否是链接列
   *
   * @author lxm
   * @date 2022-09-28 17:09:15
   * @returns {*}
   */
  get isLinkColumn(): boolean {
    return !!this.model.enableLinkView && !!this.model.linkAppViewId;
  }

  /**
   * 是否有触发界面行为
   *
   * @author lxm
   * @date 2022-12-08 14:12:37
   * @readonly
   * @type {boolean}
   */
  get hasAction(): boolean {
    return !!this.model.deuiactionId;
  }

  /**
   * 行是否可点击（影响列的界面样式）
   *
   * @author lxm
   * @date 2022-12-08 15:12:58
   * @readonly
   */
  clickable(row: GridRowState): boolean {
    const value = row.data[this.model.codeName!];
    return (this.isLinkColumn || this.hasAction) && value;
  }

  /**
   * 公共参数处理，计算上下文和视图参数
   * @return {*}
   * @author: zhujiamin
   * @Date: 2022-08-25 15:44:14
   */
  public handlePublicParams(
    data: IData,
    context: IContext,
    params: IParams,
  ): { context: IContext; params: IParams } {
    // todo 从userParams里转出导航参数
    const { userParam } = this.model;
    if (!userParam) {
      return { context, params };
    }
    const { navigateContexts, navigateParams } = parseUserParams(userParam);
    let selfContext = {};
    if (navigateContexts && data) {
      selfContext = convertNavData(navigateContexts!, context, params, data);
    }
    const _context = Object.assign(context.clone(), selfContext);
    let selfParams = {};
    if (navigateParams && data) {
      selfParams = convertNavData(navigateParams!, context, params, data);
    }
    const _params: IParams = { ...params, ...selfParams };
    return { context: _context, params: _params };
  }

  /**
   * 打开链接视图
   *
   * @author lxm
   * @date 2022-09-28 18:09:14
   * @param {GridRowState} row 行数据
   * @param {MouseEvent} event 原生事件
   * @returns {*}  {Promise<void>}
   */
  async openLinkView(row: GridRowState, event: MouseEvent): Promise<void> {
    const curValue = row.data[this.model.codeName!];
    if (!curValue) {
      // 当前值不存在，不继续走打开链接视图逻辑
      return;
    }
    const valueItem = this.model.linkValueItem || 'srfkey';
    const value = row.data[valueItem];
    if (value == null) {
      throw new ModelError(this.model, `未在行数据中取到 ${valueItem} 的值`);
    }
    const { linkAppViewId } = this.model;
    if (!linkAppViewId) {
      return;
    }
    const wfContext = getWFContext(row.data);
    const tempContext = Object.assign(this.context.clone(), {
      srfkey: value,
      ...wfContext,
    });
    const tempParams = clone(this.params);
    const { context: newContext, params: newParams } = this.handlePublicParams(
      row.data,
      tempContext,
      tempParams,
    );
    // 打开视图
    const res: IModalData = await ibiz.commands.execute(
      OpenAppViewCommand.TAG,
      linkAppViewId,
      newContext,
      newParams,
      { event },
    );
    if (res?.ok) {
      this.grid.load();
    }
  }

  /**
   * 触发表格列附加界面行为
   *
   * @author lxm
   * @date 2022-12-08 15:12:35
   * @param {GridRowState} row 行数据
   * @param {MouseEvent} event 鼠标事件
   * @returns {*}  {Promise<void>}
   */
  async triggerAction(_row: GridRowState, _event: MouseEvent): Promise<void> {
    // if (this.model.viewLogic) {
    //   await executeViewLogic(
    //     this.model.viewLogic,
    //     this.context,
    //     [row.data],
    //     this.params,
    //     {
    //       event,
    //       neuron: this.grid.nerve.self,
    //       view: this.grid.ctx.view,
    //     },
    //   );
    // }
  }

  /**
   * 加载代码表数据
   *
   * @author lxm
   * @date 2022-09-28 15:09:38
   * @returns {*}
   */
  async loadCodeList(): Promise<Readonly<CodeListItem[]> | undefined> {
    const appCodeListId = this.model.appCodeListId!;
    if (!appCodeListId) {
      return;
    }
    const app = ibiz.hub.getApp(this.context.srfappid);

    // 顺便加载代码表模型
    if (!this.codeList) {
      this.codeList = app.codeList.getCodeList(appCodeListId);
    }

    const dataItems = await app.codeList.get(
      appCodeListId,
      this.context,
      this.params,
    );
    this.codeListItems = dataItems;
    return dataItems;
  }

  /**
   * 计算聚合属性列的值
   * 无配置返回undefined
   * @author lxm
   * @date 2023-08-07 04:50:47
   * @param {IData[]} items
   * @return {*}  {(string | undefined)}
   */
  calcFieldAgg(items: IData[]): string | undefined {
    const { aggField, aggMode, aggValueFormat } = this.model;
    // 无聚合配置的列，返回undefined
    if (aggMode === 'NONE') {
      return;
    }
    const fieldName = aggField || this.model.id!;
    let aggValue: number;
    if (this.grid.model.aggMode === 'PAGE') {
      switch (aggMode) {
        case 'SUM':
          aggValue = items
            .map(item => item[fieldName] as number)
            .reduce((a, b) => a + b, 0);
          break;
        case 'AVG':
          aggValue =
            items
              .map(item => item[fieldName] as number)
              .reduce((a, b) => a + b, 0) / items.length;
          break;
        case 'MAX':
          aggValue = Math.max(...items.map(item => item[fieldName] as number));
          break;
        case 'MIN':
          aggValue = Math.min(...items.map(item => item[fieldName] as number));
          break;
        default:
          throw new ModelError(this.model, `暂未支持属性列聚合模式${aggMode}`);
      }
    } else if (this.grid.model.aggMode === 'ALL') {
      // if (!this.grid.state.remoteAggResult) {
      //   throw new RuntimeError(`没有远程聚合数据`);
      // }
      // aggValue = this.grid.state.remoteAggResult[fieldName];
      // if (!aggValue) {
      //   throw new RuntimeError(`远程聚合数据里缺少${fieldName}的值`);
      // }
      throw new ModelError(this.model, `远程聚合暂未支持`);
    } else {
      throw new ModelError(
        this.grid.model,
        `暂未支持聚合模式${this.grid.model.aggMode}`,
      );
    }
    if (!aggValueFormat) {
      return `${aggValue}`;
    }

    // 聚合值格式化
    const formatValue: string = '';
    switch (aggValueFormat) {
      default:
        throw new ModelError(
          this.model,
          `暂未支持${aggValueFormat}的聚合值格式化`,
        );
    }
    return formatValue;
  }
}
